# -*- coding: utf-8 -*-



## ------------------------------------------------------------
## Copyright 2010 Pierre-Antoine Delsart
## 
## This file is part of LeVin.
## 
## LeVin is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
## 
## LeVin is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
## 
## You should have received a copy of the GNU General Public License
## along with LeVin.  If not, see <http://www.gnu.org/licenses/>.
## ---------------------------------------------------------------

import pod
import pod.list

colors = ["Red","White","Pink"]


# improve pod.Objects --------------------------------
def specialAttributes(cls):
    return []
def getDBAttributes(cls):
    if hasattr(cls,'_DBattributes'):
        return cls._DBattributes
    
    cls._DBattributes = [k for k in cls.__dict__.keys() if isinstance(getattr(cls,k) , pod.typed.Typed)  ] + cls.specialAttributes()
    return cls._DBattributes

def dumpAsDict(self):
    d = {}
    excl = set( self.attExcludedFromDump  )
    for k in self.getDBAttributes() :
        if k in excl: continue
        try : 
            a = getattr(self,k)
            if a is None :
                continue
            if isinstance(a,pod.list.List) :
                a = [ i.dumpAsDict() for i in a ]
            d[k] = a
        except:
            pass
    return d

pod.Object.getDBAttributes = classmethod(getDBAttributes)
pod.Object.specialAttributes = classmethod(specialAttributes)
pod.Object.dumpAsDict = dumpAsDict
pod.Object.attExcludedFromDump = []
# ---------------------------------------------------------

class Transiant(pod.NoSave):
    pass
class TmpAtt(pod.NoSave):
    pass

class Tasting(pod.Object):    
    date    = pod.typed.Time(date_string = '%d-%m-%Y', local_time = True)
    #year    = pod.typed.Int()
    rate    = pod.typed.Int()
    comment = pod.typed.Unicode()
    #excl 

    visual_color = pod.typed.Unicode()
    visual_viscosity = pod.typed.Unicode()
    visual_shine = pod.typed.Unicode()
    visual_more = pod.typed.Unicode()

    smell_first = pod.typed.Unicode()
    smell_strength = pod.typed.Unicode()
    smell_aroma = pod.typed.Unicode()
    smell_more = pod.typed.Unicode()

    taste_start = pod.typed.Unicode()
    taste_balance = pod.typed.Unicode()
    taste_body = pod.typed.Unicode()
    taste_final = pod.typed.Unicode()
    taste_length = pod.typed.Unicode()
    taste_more = pod.typed.Unicode()

    bottle    = pod.typed.Object() # 
    attExcludedFromDump = ['bottle']


    def __init__(self, **args):
        pod.Object.__init__(self,**args)
        print 'Build new Tasting', args
        self.trans = TmpAtt()
    def on_load_from_db(self):
        self.trans = TmpAtt()
        #print 't=', self.trans
        
    def dic(self):
        return dict(self.iteritems() )



DBVERSION = 1
    

class BottleBase(pod.Object):
    color   = pod.typed.Int()
    country = pod.typed.Unicode()
    region  = pod.typed.Unicode()
    appellation = pod.typed.Unicode()
    cru_name = pod.typed.Unicode()
    millesime=pod.typed.Time(date_string = '%Y', local_time = True)
    volume=pod.typed.Int()
    alcohol  = pod.typed.Float() 
    productor = pod.typed.Unicode() 
    numInStock = pod.typed.Int()
    pricePerBottle = pod.typed.Float()
    cepage = pod.typed.Unicode()
    localisation = pod.typed.String()
    otherInfo = pod.typed.Unicode()

class BottleSuggestion(BottleBase):
    suggestedFrom  = pod.typed.Unicode()
    suggestedTo    = pod.typed.Unicode()    
    pass

class BottleSet(pod.Object):
    color   = pod.typed.Int()
    country = pod.typed.Unicode()
    region  = pod.typed.Unicode()
    appellation = pod.typed.Unicode()
    cru_name = pod.typed.Unicode()
    millesime=pod.typed.Time(date_string = '%Y', local_time = True)
    volume=pod.typed.Int()
    meanrate = pod.typed.Float()
    alcohol  = pod.typed.Float() 
    productor = pod.typed.Unicode() 
    numInStock = pod.typed.Int()
    pricePerBottle = pod.typed.Float()
    acquireDate = pod.typed.Time(date_string = '%d-%m-%Y', local_time = True)
    acquireComment = pod.typed.Unicode()
    cepage = pod.typed.Unicode()
    geolocalisation = pod.typed.String()
    otherInfo = pod.typed.Unicode()

    suggestedFrom  = pod.typed.Unicode()
    suggestedTo    = pod.typed.Unicode()    


    optimalMax = pod.typed.Int()
    optimalMin = pod.typed.Int()    

    @classmethod
    def specialAttributes(cls):
        return ['tastings']
    
    def __init__(self, **args):
        tt = None
        if 'tastings' in args:
            tt = args.pop('tastings')
        pod.Object.__init__(self,**args)
        self.transiant = Transiant()
        self.tastings = pod.list.List()        

        if tt :
            for t in tt:
                t['bottle'] = self
                self.tastings.append(Tasting(**t))
        

    def on_load_from_db(self):
        self.transiant = Transiant()

    def addTasting(self,t):
        t.bottle = self
        N = len(self.tastings)
        r = N * (self.meanrate if self.meanrate is not None else 0)
        self.tastings.append(t)
        self.meanrate = (r + t.rate)/(N+1)

db = None
def openDB(fname):
    global db
    db = pod.Db(file = fname, dynamic_index = True)
    db.store.version = DBVERSION
    
def createWine(n=10):
    for i in range(n):
        dic = { 'country':'France', 'region':'Region num '+str(int(i/4))}
        date='10-10-2010'
        v1=BottleSet(cru_name='Givds dry', millesime = '2001', appellation='Gdasdry', volume=75,color="Red" , acquireDate=date, **dic)
        BottleSet(cru_name='bla bla', millesime = '2002', appellation='sdas Rotie', volume=75,color="Blanc",acquireDate=date,**dic)
        BottleSet(cru_name='bdv r a', millesime = '1999', appellation='SDcd ds', volume=75,color="Red",acquireDate=date,**dic)
        BottleSet(cru_name='bdsasAsa', millesime = '1987', appellation=' opdmjdDA', volume=75,color=u"Rosé",acquireDate=date,**dic)
        BottleSet(cru_name=u'ERC ére  bla', millesime = '2002', appellation=u'Cote  éàè sda', volume=75,color="Red",acquireDate=date,**dic)
        db.commit()

def createWineBlind(n=10):
    import random
    import string
    import wineAreas
    wineAreas.default_wineWorld()
    wineWorld = wineAreas.wineWorld
    char_set = string.ascii_letters + string.digits
    print ''.join(random.sample(char_set,6))


    names = {
        "Bordeaux" : [
        [ u"Médoc",u"Haut Médoc", u"Bordeaux Supérieur", u"Saint-Émilion" ],
        [u"Château Bla",u"Château Abcde", u"Château Zyxw de Xyz" ,u"Château D'eau",u"Château MontSégur"]
        ],
        "Bourgogne" : [
        ["Volnay","Fixin","Santenay","Corton","Beaune"],
        ["Le cru A","Clos de Geouvot","Le cru Z",u"Domaine Comané-Ronti",u"Áèuô","Pammord"]
        ],
        "Jura" : [
        [u"Comté", "Morbier"],
        ["Vieux", u"Tres affiné",]
        ]

        }
    def word(i):
        return ''.join(random.sample(char_set,i))

    years = range(1990,2010)
    def year():
        return str(random.choice(years))

    print year() , years
    def addTesting(v):
        t=Tasting(year=2010,comment='dsa blabal',rate=random.randrange(0,10))
        v.addTasting( t)
    for i in range(3):
        #cou = random.choice( wineWorld.subAreas.keys() )
        cou = "France"
        dic = { 'country': cou}
        for i in range(8):
            region = random.choice(names.keys() )
            dic['region'] = region
            dic['numInStock'] = random.randrange(0,7)
            dic['cepage'] = word(6)
            dic['acquireComment'] = word(3) + " sda dkeow dsdjli smaksl ms "+word(6)
            date='10-10-2010'
            r = random.randrange(0,10)
            r = None if r==0 else r
            v = BottleSet(cru_name=random.choice( names[region][1] ), appellation= random.choice( names[region][0] ),
                          millesime = year(), color = random.randint(0,2),volume=75,acquireDate=date,**dic)
            for i in xrange(random.randint(0,2)):
                addTesting(v)

    db.commit()


def addTasting(b , **args):
    t = Tasting(**args)
    b.addTasting(t)
    db.commit()
    
def fillNewBottle(values, tastings=[]):
    v = BottleSet( **values)
    for t in tastings:
        v.tastings.append( Tasting(**t) )
    db.commit()
    return v


def updateBottleFunction(w):
    def updateBottle(values, tastings=[]):
        w.set_many( **values)
        w.tastings.clear()
        
        for t in tastings:
            w.tastings.append( Tasting(**t) )
        db.commit()
        return w
    return updateBottle
    

def dumpDB():
    for v in BottleSet:

        print u' '.join( k+':'+unicode(val) for k,val in v.iteritems() if val is not None)

def jsonDump(fname):
    f = open(fname,'w')
    import json
    l = [ v.dumpAsDict() for v in BottleSet ]
    json.dump(l,f,indent=4)
    f.close()
    
def readFromJson(fname):
    f = open(fname)
    import json
    l = json.load(f)
    for v in  l:
        BottleSet(**v)
    db.commit()
    

def dumpTastings():
    print 'tt=['
    for b in BottleSet :
        if len(b.tastings) == 0:
            continue

        print u'(  ( u"%s", u"%s", u"%s") , '%( b.region, b.appellation, b.cru_name)
        print 'dics=['
        for t in b.tastings:
            print t.dic(), ','
        print ']'
        print '),'
    print ']'

